"""
市场分析模块

提供市场趋势分析、行业轮动分析、市场情绪分析、技术指标分析等功能。
支持中国A股、期货、ETF、期权、债券等金融标的的市场分析。
"""

import asyncio
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Tuple, Union, Any
from enum import Enum
from dataclasses import dataclass, field
import pandas as pd
import numpy as np
from abc import ABC, abstractmethod


class TrendDirection(Enum):
    """趋势方向枚举"""
    STRONG_UPTREND = "strong_uptrend"
    UPTREND = "uptrend"
    SIDEWAYS = "sideways"
    DOWNTREND = "downtrend"
    STRONG_DOWNTREND = "strong_downtrend"


class MarketRegime(Enum):
    """市场状态枚举"""
    BULL_MARKET = "bull_market"
    BEAR_MARKET = "bear_market"
    RANGE_BOUND = "range_bound"
    VOLATILE = "volatile"
    CRISIS = "crisis"


class SentimentLevel(Enum):
    """情绪水平枚举"""
    EXTREME_FEAR = "extreme_fear"
    FEAR = "fear"
    NEUTRAL = "neutral"
    GREED = "greed"
    EXTREME_GREED = "extreme_greed"


class TechnicalIndicator(Enum):
    """技术指标枚举"""
    SMA = "sma"  # 简单移动平均
    EMA = "ema"  # 指数移动平均
    RSI = "rsi"  # 相对强弱指数
    MACD = "macd"  # MACD指标
    BOLLINGER_BANDS = "bollinger_bands"  # 布林带
    STOCHASTIC = "stochastic"  # 随机指标
    ATR = "atr"  # 平均真实波幅
    VOLUME_MA = "volume_ma"  # 成交量移动平均
    OBV = "obv"  # 能量潮指标
    CCI = "cci"  # 商品通道指数


@dataclass
class TrendAnalysisResult:
    """趋势分析结果"""
    symbol: str
    direction: TrendDirection
    strength: float  # 趋势强度 0-1
    confidence: float  # 置信度 0-1
    support_levels: List[float] = field(default_factory=list)
    resistance_levels: List[float] = field(default_factory=list)
    trend_start_date: Optional[datetime] = None
    expected_duration: Optional[int] = None  # 预期持续天数
    analysis_date: datetime = field(default_factory=datetime.now)


@dataclass
class MarketRegimeResult:
    """市场状态分析结果"""
    regime: MarketRegime
    probability: float  # 概率 0-1
    volatility_level: float  # 波动率水平
    correlation_breakdown: bool  # 相关性是否失效
    regime_duration: int  # 当前状态持续天数
    transition_probability: Dict[MarketRegime, float] = field(default_factory=dict)
    analysis_date: datetime = field(default_factory=datetime.now)


@dataclass
class SentimentAnalysisResult:
    """情绪分析结果"""
    overall_sentiment: SentimentLevel
    sentiment_score: float  # 情绪得分 -1到1
    fear_greed_index: float  # 恐惧贪婪指数 0-100
    put_call_ratio: float  # 看跌看涨比率
    vix_level: float  # 波动率指数
    margin_debt_ratio: float  # 融资融券比率
    insider_trading_ratio: float  # 内部交易比率
    analysis_date: datetime = field(default_factory=datetime.now)


@dataclass
class SectorRotationResult:
    """行业轮动分析结果"""
    leading_sectors: List[str]  # 领先行业
    lagging_sectors: List[str]  # 滞后行业
    rotation_stage: str  # 轮动阶段
    sector_momentum: Dict[str, float]  # 行业动量
    relative_strength: Dict[str, float]  # 相对强度
    rotation_probability: float  # 轮动概率
    analysis_date: datetime = field(default_factory=datetime.now)


@dataclass
class TechnicalIndicatorResult:
    """技术指标分析结果"""
    indicator: TechnicalIndicator
    value: Union[float, Dict[str, float]]
    signal: str  # 信号：买入、卖出、持有
    strength: float  # 信号强度 0-1
    divergence: bool  # 是否存在背离
    overbought: bool  # 是否超买
    oversold: bool  # 是否超卖
    analysis_date: datetime = field(default_factory=datetime.now)


class BaseTechnicalIndicator(ABC):
    """技术指标基类"""
    
    def __init__(self, period: int = 14):
        self.period = period
    
    @abstractmethod
    async def calculate(self, data: pd.DataFrame) -> TechnicalIndicatorResult:
        """计算技术指标"""
        pass
    
    def _validate_data(self, data: pd.DataFrame) -> bool:
        """验证数据有效性"""
        required_columns = ['open', 'high', 'low', 'close', 'volume']
        return all(col in data.columns for col in required_columns)


class RSIIndicator(BaseTechnicalIndicator):
    """RSI相对强弱指数"""
    
    async def calculate(self, data: pd.DataFrame) -> TechnicalIndicatorResult:
        """计算RSI指标"""
        if not self._validate_data(data):
            raise ValueError("数据格式不正确")
        
        close_prices = data['close']
        delta = close_prices.diff()
        
        gain = (delta.where(delta > 0, 0)).rolling(window=self.period).mean()
        loss = (-delta.where(delta < 0, 0)).rolling(window=self.period).mean()
        
        rs = gain / loss
        rsi = 100 - (100 / (1 + rs))
        
        current_rsi = float(rsi.iloc[-1])
        
        # 判断信号
        if current_rsi > 70:
            signal = "卖出"
            overbought = True
            oversold = False
        elif current_rsi < 30:
            signal = "买入"
            overbought = False
            oversold = True
        else:
            signal = "持有"
            overbought = False
            oversold = False
        
        # 计算信号强度
        if current_rsi > 80 or current_rsi < 20:
            strength = 0.9
        elif current_rsi > 70 or current_rsi < 30:
            strength = 0.7
        else:
            strength = 0.3
        
        # 检测背离
        divergence = self._detect_divergence(data, rsi)
        
        return TechnicalIndicatorResult(
            indicator=TechnicalIndicator.RSI,
            value=current_rsi,
            signal=signal,
            strength=strength,
            divergence=divergence,
            overbought=overbought,
            oversold=oversold
        )
    
    def _detect_divergence(self, price_data: pd.DataFrame, indicator_data: pd.Series) -> bool:
        """检测价格与指标的背离"""
        # 简化的背离检测逻辑
        if len(price_data) < 20:
            return False
        
        recent_prices = price_data['close'].tail(10)
        recent_indicator = indicator_data.tail(10)
        
        price_trend = recent_prices.iloc[-1] > recent_prices.iloc[0]
        indicator_trend = recent_indicator.iloc[-1] > recent_indicator.iloc[0]
        
        return price_trend != indicator_trend


class MACDIndicator(BaseTechnicalIndicator):
    """MACD指标"""
    
    def __init__(self, fast_period: int = 12, slow_period: int = 26, signal_period: int = 9):
        self.fast_period = fast_period
        self.slow_period = slow_period
        self.signal_period = signal_period
    
    async def calculate(self, data: pd.DataFrame) -> TechnicalIndicatorResult:
        """计算MACD指标"""
        if not self._validate_data(data):
            raise ValueError("数据格式不正确")
        
        close_prices = data['close']
        
        # 计算EMA
        ema_fast = close_prices.ewm(span=self.fast_period).mean()
        ema_slow = close_prices.ewm(span=self.slow_period).mean()
        
        # 计算MACD线
        macd_line = ema_fast - ema_slow
        
        # 计算信号线
        signal_line = macd_line.ewm(span=self.signal_period).mean()
        
        # 计算柱状图
        histogram = macd_line - signal_line
        
        current_macd = float(macd_line.iloc[-1])
        current_signal = float(signal_line.iloc[-1])
        current_histogram = float(histogram.iloc[-1])
        
        # 判断信号
        if current_macd > current_signal and histogram.iloc[-2] < 0:
            signal = "买入"
            strength = 0.8
        elif current_macd < current_signal and histogram.iloc[-2] > 0:
            signal = "卖出"
            strength = 0.8
        else:
            signal = "持有"
            strength = 0.3
        
        # 检测背离
        # 检测背离 - 简化实现
        divergence = False
        if len(data) >= 20:
            recent_prices = data['close'].tail(10)
            recent_macd = macd_line.tail(10)
            price_trend = recent_prices.iloc[-1] > recent_prices.iloc[0]
            macd_trend = recent_macd.iloc[-1] > recent_macd.iloc[0]
            divergence = price_trend != macd_trend
        
        return TechnicalIndicatorResult(
            indicator=TechnicalIndicator.MACD,
            value={
                'macd': current_macd,
                'signal': current_signal,
                'histogram': current_histogram
            },
            signal=signal,
            strength=strength,
            divergence=divergence,
            overbought=False,
            oversold=False
        )


class BollingerBandsIndicator(BaseTechnicalIndicator):
    """布林带指标"""
    
    def __init__(self, period: int = 20, std_dev: float = 2.0):
        super().__init__(period)
        self.std_dev = std_dev
    
    async def calculate(self, data: pd.DataFrame) -> TechnicalIndicatorResult:
        """计算布林带指标"""
        if not self._validate_data(data):
            raise ValueError("数据格式不正确")
        
        close_prices = data['close']
        
        # 计算中轨（移动平均）
        middle_band = close_prices.rolling(window=self.period).mean()
        
        # 计算标准差
        std = close_prices.rolling(window=self.period).std()
        
        # 计算上轨和下轨
        upper_band = middle_band + (std * self.std_dev)
        lower_band = middle_band - (std * self.std_dev)
        
        current_price = float(close_prices.iloc[-1])
        current_upper = float(upper_band.iloc[-1])
        current_middle = float(middle_band.iloc[-1])
        current_lower = float(lower_band.iloc[-1])
        
        # 判断信号
        if current_price > current_upper:
            signal = "卖出"
            strength = 0.7
            overbought = True
            oversold = False
        elif current_price < current_lower:
            signal = "买入"
            strength = 0.7
            overbought = False
            oversold = True
        else:
            signal = "持有"
            strength = 0.3
            overbought = False
            oversold = False
        
        # 计算带宽
        bandwidth = (current_upper - current_lower) / current_middle
        
        return TechnicalIndicatorResult(
            indicator=TechnicalIndicator.BOLLINGER_BANDS,
            value={
                'upper': current_upper,
                'middle': current_middle,
                'lower': current_lower,
                'bandwidth': bandwidth,
                'position': (current_price - current_lower) / (current_upper - current_lower)
            },
            signal=signal,
            strength=strength,
            divergence=False,
            overbought=overbought,
            oversold=oversold
        )


class MarketAnalyzer:
    """市场分析器主类"""
    
    def __init__(self):
        self.indicators = {
            TechnicalIndicator.RSI: RSIIndicator(),
            TechnicalIndicator.MACD: MACDIndicator(),
            TechnicalIndicator.BOLLINGER_BANDS: BollingerBandsIndicator()
        }
    
    async def analyze_trend(
        self,
        data: pd.DataFrame,
        symbol: str,
        lookback_period: int = 50
    ) -> TrendAnalysisResult:
        """分析价格趋势"""
        if len(data) < lookback_period:
            raise ValueError(f"数据长度不足，需要至少{lookback_period}个数据点")
        
        close_prices = data['close'].tail(lookback_period)
        high_prices = data['high'].tail(lookback_period)
        low_prices = data['low'].tail(lookback_period)
        
        # 计算移动平均线
        sma_short = close_prices.rolling(window=10).mean()
        sma_long = close_prices.rolling(window=30).mean()
        
        # 判断趋势方向
        current_price = close_prices.iloc[-1]
        sma_short_current = sma_short.iloc[-1]
        sma_long_current = sma_long.iloc[-1]
        
        if current_price > sma_short_current > sma_long_current:
            if (current_price - sma_long_current) / sma_long_current > 0.1:
                direction = TrendDirection.STRONG_UPTREND
                strength = 0.9
            else:
                direction = TrendDirection.UPTREND
                strength = 0.7
        elif current_price < sma_short_current < sma_long_current:
            if (sma_long_current - current_price) / sma_long_current > 0.1:
                direction = TrendDirection.STRONG_DOWNTREND
                strength = 0.9
            else:
                direction = TrendDirection.DOWNTREND
                strength = 0.7
        else:
            direction = TrendDirection.SIDEWAYS
            strength = 0.3
        
        # 计算支撑和阻力位
        support_levels = self._calculate_support_levels(low_prices)
        resistance_levels = self._calculate_resistance_levels(high_prices)
        
        # 计算置信度
        confidence = self._calculate_trend_confidence(close_prices, direction)
        
        return TrendAnalysisResult(
            symbol=symbol,
            direction=direction,
            strength=strength,
            confidence=confidence,
            support_levels=support_levels,
            resistance_levels=resistance_levels,
            trend_start_date=self._estimate_trend_start(data, direction),
            expected_duration=self._estimate_trend_duration(data, direction)
        )
    
    async def analyze_market_regime(
        self,
        market_data: Dict[str, pd.DataFrame],
        lookback_period: int = 252
    ) -> MarketRegimeResult:
        """分析市场状态"""
        # 计算市场整体收益率
        market_returns = []
        for symbol, data in market_data.items():
            if len(data) >= lookback_period:
                returns = data['close'].pct_change().tail(lookback_period)
                market_returns.append(returns)
        
        if not market_returns:
            raise ValueError("没有足够的市场数据")
        
        # 计算平均市场收益率
        avg_returns = pd.concat(market_returns, axis=1).mean(axis=1)
        
        # 计算波动率
        volatility = avg_returns.std() * np.sqrt(252)
        
        # 计算累积收益
        cumulative_returns = (1 + avg_returns).cumprod()
        
        # 判断市场状态
        recent_performance = cumulative_returns.iloc[-1] / cumulative_returns.iloc[-63] - 1  # 3个月表现
        
        if recent_performance > 0.15 and volatility < 0.2:
            regime = MarketRegime.BULL_MARKET
            probability = 0.8
        elif recent_performance < -0.15 and volatility > 0.3:
            regime = MarketRegime.BEAR_MARKET
            probability = 0.8
        elif volatility > 0.4:
            regime = MarketRegime.VOLATILE
            probability = 0.7
        elif abs(recent_performance) < 0.05:
            regime = MarketRegime.RANGE_BOUND
            probability = 0.6
        else:
            regime = MarketRegime.VOLATILE
            probability = 0.5
        
        # 检查相关性失效
        correlation_breakdown = self._check_correlation_breakdown(market_data)
        
        # 计算状态转换概率
        transition_prob = self._calculate_transition_probabilities(avg_returns, regime)
        
        return MarketRegimeResult(
            regime=regime,
            probability=probability,
            volatility_level=volatility,
            correlation_breakdown=correlation_breakdown,
            regime_duration=self._calculate_regime_duration(avg_returns, regime),
            transition_probability=transition_prob
        )
    
    async def analyze_sentiment(
        self,
        market_data: pd.DataFrame,
        sentiment_indicators: Dict[str, float]
    ) -> SentimentAnalysisResult:
        """分析市场情绪"""
        # 从输入参数获取情绪指标
        put_call_ratio = sentiment_indicators.get('put_call_ratio', 1.0)
        vix_level = sentiment_indicators.get('vix', 20.0)
        margin_debt_ratio = sentiment_indicators.get('margin_debt_ratio', 0.1)
        insider_trading_ratio = sentiment_indicators.get('insider_trading_ratio', 0.5)
        
        # 计算恐惧贪婪指数
        fear_greed_index = self._calculate_fear_greed_index(
            put_call_ratio, vix_level, margin_debt_ratio, insider_trading_ratio
        )
        
        # 计算综合情绪得分
        sentiment_score = (fear_greed_index - 50) / 50  # 转换为-1到1的范围
        
        # 判断情绪水平
        if fear_greed_index < 20:
            sentiment_level = SentimentLevel.EXTREME_FEAR
        elif fear_greed_index < 40:
            sentiment_level = SentimentLevel.FEAR
        elif fear_greed_index < 60:
            sentiment_level = SentimentLevel.NEUTRAL
        elif fear_greed_index < 80:
            sentiment_level = SentimentLevel.GREED
        else:
            sentiment_level = SentimentLevel.EXTREME_GREED
        
        return SentimentAnalysisResult(
            overall_sentiment=sentiment_level,
            sentiment_score=sentiment_score,
            fear_greed_index=fear_greed_index,
            put_call_ratio=put_call_ratio,
            vix_level=vix_level,
            margin_debt_ratio=margin_debt_ratio,
            insider_trading_ratio=insider_trading_ratio
        )
    
    async def analyze_sector_rotation(
        self,
        sector_data: Dict[str, pd.DataFrame],
        lookback_period: int = 63
    ) -> SectorRotationResult:
        """分析行业轮动"""
        sector_returns = {}
        sector_momentum = {}
        relative_strength = {}
        
        # 计算各行业的收益率和动量
        for sector, data in sector_data.items():
            if len(data) >= lookback_period:
                returns = data['close'].pct_change().tail(lookback_period)
                sector_returns[sector] = returns
                
                # 计算动量（过去一个月相对于过去三个月的表现）
                recent_return = (data['close'].iloc[-1] / data['close'].iloc[-21] - 1)
                longer_return = (data['close'].iloc[-1] / data['close'].iloc[-63] - 1)
                momentum = recent_return - longer_return
                sector_momentum[sector] = momentum
                
                # 计算相对强度
                market_return = returns.mean()
                sector_return = returns.mean()
                relative_strength[sector] = sector_return - market_return
        
        # 排序确定领先和滞后行业
        sorted_momentum = sorted(sector_momentum.items(), key=lambda x: x[1], reverse=True)
        leading_sectors = [sector for sector, _ in sorted_momentum[:3]]
        lagging_sectors = [sector for sector, _ in sorted_momentum[-3:]]
        
        # 判断轮动阶段
        rotation_stage = self._determine_rotation_stage(sector_momentum, relative_strength)
        
        # 计算轮动概率
        momentum_variance = np.var(list(sector_momentum.values()))
        rotation_probability = min(momentum_variance * 10, 1.0)  # 简化的概率计算
        
        return SectorRotationResult(
            leading_sectors=leading_sectors,
            lagging_sectors=lagging_sectors,
            rotation_stage=rotation_stage,
            sector_momentum=sector_momentum,
            relative_strength=relative_strength,
            rotation_probability=rotation_probability
        )
    
    async def calculate_technical_indicator(
        self,
        data: pd.DataFrame,
        indicator: TechnicalIndicator,
        **kwargs
    ) -> TechnicalIndicatorResult:
        """计算技术指标"""
        if indicator not in self.indicators:
            raise ValueError(f"不支持的技术指标: {indicator}")
        
        indicator_calculator = self.indicators[indicator]
        
        # 如果有额外参数，创建新的指标实例
        if kwargs:
            if indicator == TechnicalIndicator.RSI:
                period = kwargs.get('period', 14)
                indicator_calculator = RSIIndicator(period)
            elif indicator == TechnicalIndicator.MACD:
                fast = kwargs.get('fast_period', 12)
                slow = kwargs.get('slow_period', 26)
                signal = kwargs.get('signal_period', 9)
                indicator_calculator = MACDIndicator(fast, slow, signal)
            elif indicator == TechnicalIndicator.BOLLINGER_BANDS:
                period = kwargs.get('period', 20)
                std_dev = kwargs.get('std_dev', 2.0)
                indicator_calculator = BollingerBandsIndicator(period, std_dev)
        
        return await indicator_calculator.calculate(data)
    
    async def comprehensive_market_analysis(
        self,
        market_data: Dict[str, pd.DataFrame],
        sector_data: Dict[str, pd.DataFrame],
        sentiment_indicators: Dict[str, float],
        target_symbol: str
    ) -> Dict[str, Any]:
        """综合市场分析"""
        results = {}
        
        # 趋势分析
        if target_symbol in market_data:
            trend_result = await self.analyze_trend(
                market_data[target_symbol], 
                target_symbol
            )
            results['trend_analysis'] = trend_result
        
        # 市场状态分析
        regime_result = await self.analyze_market_regime(market_data)
        results['market_regime'] = regime_result
        
        # 情绪分析
        if target_symbol in market_data:
            sentiment_result = await self.analyze_sentiment(
                market_data[target_symbol],
                sentiment_indicators
            )
            results['sentiment_analysis'] = sentiment_result
        
        # 行业轮动分析
        if sector_data:
            rotation_result = await self.analyze_sector_rotation(sector_data)
            results['sector_rotation'] = rotation_result
        
        # 技术指标分析
        if target_symbol in market_data:
            technical_results = {}
            for indicator in [TechnicalIndicator.RSI, TechnicalIndicator.MACD, TechnicalIndicator.BOLLINGER_BANDS]:
                try:
                    indicator_result = await self.calculate_technical_indicator(
                        market_data[target_symbol],
                        indicator
                    )
                    technical_results[indicator.value] = indicator_result
                except Exception as e:
                    technical_results[indicator.value] = f"计算失败: {str(e)}"
            
            results['technical_indicators'] = technical_results
        
        # 综合评分
        results['overall_score'] = self._calculate_overall_score(results)
        results['analysis_timestamp'] = datetime.now()
        
        return results
    
    def _calculate_support_levels(self, low_prices: pd.Series) -> List[float]:
        """计算支撑位"""
        # 简化的支撑位计算
        recent_lows = low_prices.tail(20)
        support_levels = []
        
        for i in range(2, len(recent_lows) - 2):
            if (recent_lows.iloc[i] < recent_lows.iloc[i-1] and 
                recent_lows.iloc[i] < recent_lows.iloc[i+1] and
                recent_lows.iloc[i] < recent_lows.iloc[i-2] and 
                recent_lows.iloc[i] < recent_lows.iloc[i+2]):
                support_levels.append(float(recent_lows.iloc[i]))
        
        return sorted(support_levels)[-3:]  # 返回最近的3个支撑位
    
    def _calculate_resistance_levels(self, high_prices: pd.Series) -> List[float]:
        """计算阻力位"""
        # 简化的阻力位计算
        recent_highs = high_prices.tail(20)
        resistance_levels = []
        
        for i in range(2, len(recent_highs) - 2):
            if (recent_highs.iloc[i] > recent_highs.iloc[i-1] and 
                recent_highs.iloc[i] > recent_highs.iloc[i+1] and
                recent_highs.iloc[i] > recent_highs.iloc[i-2] and 
                recent_highs.iloc[i] > recent_highs.iloc[i+2]):
                resistance_levels.append(float(recent_highs.iloc[i]))
        
        return sorted(resistance_levels, reverse=True)[:3]  # 返回最近的3个阻力位
    
    def _calculate_trend_confidence(self, prices: pd.Series, direction: TrendDirection) -> float:
        """计算趋势置信度"""
        # 基于价格序列的线性回归斜率计算置信度
        x = np.arange(len(prices))
        y = prices.values
        
        # 计算相关系数
        correlation = np.corrcoef(x, y)[0, 1]
        
        if direction in [TrendDirection.UPTREND, TrendDirection.STRONG_UPTREND]:
            return max(0, correlation)
        elif direction in [TrendDirection.DOWNTREND, TrendDirection.STRONG_DOWNTREND]:
            return max(0, -correlation)
        else:
            return 1 - abs(correlation)
    
    def _estimate_trend_start(self, data: pd.DataFrame, direction: TrendDirection) -> Optional[datetime]:
        """估计趋势开始时间"""
        # 简化实现，返回30天前的日期
        if len(data) >= 30:
            try:
                # 尝试从索引获取日期
                index_date = data.index[-30]
                if hasattr(index_date, 'to_pydatetime'):
                    return getattr(index_date, 'to_pydatetime')()
                elif isinstance(index_date, datetime):
                    return index_date
                else:
                    return datetime.now() - timedelta(days=30)
            except:
                return datetime.now() - timedelta(days=30)
        return None
    
    def _estimate_trend_duration(self, data: pd.DataFrame, direction: TrendDirection) -> Optional[int]:
        """估计趋势持续时间"""
        # 简化实现，基于趋势强度估计
        if direction in [TrendDirection.STRONG_UPTREND, TrendDirection.STRONG_DOWNTREND]:
            return 60  # 强趋势预期持续60天
        elif direction in [TrendDirection.UPTREND, TrendDirection.DOWNTREND]:
            return 30  # 普通趋势预期持续30天
        else:
            return 15  # 横盘预期持续15天
    
    def _check_correlation_breakdown(self, market_data: Dict[str, pd.DataFrame]) -> bool:
        """检查相关性失效"""
        if len(market_data) < 2:
            return False
        
        # 计算股票间的相关性
        returns_data = []
        for symbol, data in market_data.items():
            if len(data) >= 30:
                returns = data['close'].pct_change().tail(30)
                returns_data.append(returns)
        
        if len(returns_data) < 2:
            return False
        
        # 计算平均相关性
        correlations = []
        for i in range(len(returns_data)):
            for j in range(i + 1, len(returns_data)):
                corr = returns_data[i].corr(returns_data[j])
                if not pd.isna(corr):
                    correlations.append(abs(corr))
        
        avg_correlation = np.mean(correlations) if correlations else 0
        return avg_correlation < 0.3  # 相关性低于0.3认为失效
    
    def _calculate_transition_probabilities(
        self, 
        returns: pd.Series, 
        current_regime: MarketRegime
    ) -> Dict[MarketRegime, float]:
        """计算状态转换概率"""
        # 简化的转换概率计算
        base_probs = {
            MarketRegime.BULL_MARKET: 0.2,
            MarketRegime.BEAR_MARKET: 0.15,
            MarketRegime.RANGE_BOUND: 0.4,
            MarketRegime.VOLATILE: 0.2,
            MarketRegime.CRISIS: 0.05
        }
        
        # 基于历史数据调整概率
        if len(returns) >= 30:
            recent_returns = returns.tail(30)
            volatility = recent_returns.std()
            mean_return = recent_returns.mean()
            
            # 根据近期表现调整概率
            if mean_return > 0.01:  # 强势上涨
                base_probs[MarketRegime.BULL_MARKET] *= 1.5
            elif mean_return < -0.01:  # 强势下跌
                base_probs[MarketRegime.BEAR_MARKET] *= 1.5
            
            if volatility > 0.02:  # 高波动
                base_probs[MarketRegime.VOLATILE] *= 2.0
            else:  # 低波动
                base_probs[MarketRegime.RANGE_BOUND] *= 1.3
        
        # 归一化概率
        total_prob = sum(base_probs.values())
        return {regime: prob / total_prob for regime, prob in base_probs.items()}
    
    def _calculate_regime_duration(self, returns: pd.Series, regime: MarketRegime) -> int:
        """计算市场状态持续时间"""
        # 简化实现，基于状态类型返回估计持续时间
        if regime == MarketRegime.BULL_MARKET:
            return 180  # 牛市平均持续6个月
        elif regime == MarketRegime.BEAR_MARKET:
            return 120  # 熊市平均持续4个月
        elif regime == MarketRegime.VOLATILE:
            return 60   # 波动期平均持续2个月
        elif regime == MarketRegime.CRISIS:
            return 30   # 危机期平均持续1个月
        else:
            return 90   # 震荡期平均持续3个月
    
    def _calculate_fear_greed_index(
        self,
        put_call_ratio: float,
        vix_level: float,
        margin_debt_ratio: float,
        insider_trading_ratio: float
    ) -> float:
        """计算恐惧贪婪指数"""
        # 各指标权重
        weights = {
            'put_call': 0.3,
            'vix': 0.4,
            'margin': 0.2,
            'insider': 0.1
        }
        
        # 标准化各指标到0-100范围
        put_call_score = max(0, min(100, (2.0 - put_call_ratio) * 50))  # 看跌看涨比率越低越贪婪
        vix_score = max(0, min(100, (50 - vix_level) * 2))  # VIX越低越贪婪
        margin_score = max(0, min(100, margin_debt_ratio * 500))  # 融资比率越高越贪婪
        insider_score = max(0, min(100, insider_trading_ratio * 100))  # 内部交易比率越高越贪婪
        
        # 加权平均
        fear_greed_index = (
            put_call_score * weights['put_call'] +
            vix_score * weights['vix'] +
            margin_score * weights['margin'] +
            insider_score * weights['insider']
        )
        
        return fear_greed_index
    
    def _determine_rotation_stage(
        self,
        sector_momentum: Dict[str, float],
        relative_strength: Dict[str, float]
    ) -> str:
        """确定行业轮动阶段"""
        # 计算动量和相对强度的分布
        momentum_values = list(sector_momentum.values())
        strength_values = list(relative_strength.values())
        
        momentum_std = np.std(momentum_values)
        strength_std = np.std(strength_values)
        
        # 基于分散程度判断轮动阶段
        if momentum_std > 0.1 and strength_std > 0.05:
            return "活跃轮动期"
        elif momentum_std > 0.05:
            return "温和轮动期"
        else:
            return "轮动停滞期"
    
    def _calculate_overall_score(self, results: Dict[str, Any]) -> float:
        """计算综合评分"""
        score = 0.5  # 基础分数
        
        # 趋势分析权重
        if 'trend_analysis' in results:
            trend = results['trend_analysis']
            if trend.direction in [TrendDirection.STRONG_UPTREND, TrendDirection.UPTREND]:
                score += 0.2 * trend.strength
            elif trend.direction in [TrendDirection.STRONG_DOWNTREND, TrendDirection.DOWNTREND]:
                score -= 0.2 * trend.strength
        
        # 市场状态权重
        if 'market_regime' in results:
            regime = results['market_regime']
            if regime.regime == MarketRegime.BULL_MARKET:
                score += 0.15
            elif regime.regime == MarketRegime.BEAR_MARKET:
                score -= 0.15
            elif regime.regime == MarketRegime.VOLATILE:
                score -= 0.1
        
        # 情绪分析权重
        if 'sentiment_analysis' in results:
            sentiment = results['sentiment_analysis']
            score += sentiment.sentiment_score * 0.1
        
        # 技术指标权重
        if 'technical_indicators' in results:
            tech_indicators = results['technical_indicators']
            buy_signals = 0
            sell_signals = 0
            total_signals = 0
            
            for indicator_name, indicator_result in tech_indicators.items():
                if hasattr(indicator_result, 'signal'):
                    total_signals += 1
                    if indicator_result.signal == "买入":
                        buy_signals += 1
                    elif indicator_result.signal == "卖出":
                        sell_signals += 1
            
            if total_signals > 0:
                signal_score = (buy_signals - sell_signals) / total_signals
                score += signal_score * 0.15
        
        return max(0, min(1, score))  # 确保分数在0-1范围内